package JPetStore.web.servlet;

import JPetStore.domain.Account;
import JPetStore.service.AccountService;
import JPetStore.service.LogService;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;

public class ChangePasswordServlet extends HttpServlet {
    private static final String MYACCOUNT = "/WEB-INF/jsp/account/MyAccount.jsp";
    private String username;
    private String password1 = null;
    private String password = null;
    private String newusername = null;
    private Account account;

    public ChangePasswordServlet() {}

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        this.password = req.getParameter("newPassword");
        this.password1 = req.getParameter("newPassword1");

        AccountService service = new AccountService();
        Account account1 = (Account) session.getAttribute("loginAccount");
        this.username = account1.getUsername();
        this.newusername = req.getParameter("firstname");

        // Validate the new username
        if (newusername == null || newusername.length() < 3 || newusername.length() > 20 || !newusername.matches("^[a-zA-Z0-9_-]+$")) {
            req.setAttribute("changePasswordMsg", "新用户名长度应为3到20之间，并且只能包含字母、数字、下划线或连字符");
            req.getRequestDispatcher(MYACCOUNT).forward(req, resp);
            return;
        }

        if (Character.isDigit(newusername.charAt(0))) {
            req.setAttribute("changePasswordMsg", "新用户名不能以数字开头");
            req.getRequestDispatcher(MYACCOUNT).forward(req, resp);
            return;
        }

        // Validate the password
        if (!password.matches("^[!@#\\$0-9a-zA-Z]+$") || !password.matches(".*[0-9].*") || password.matches("^\\d+$")) {
            req.setAttribute("changePasswordMsg", "密码必须包含数字，不能只包含数字，且只能包含字母、数字和特殊字符!@#$");
            req.getRequestDispatcher(MYACCOUNT).forward(req, resp);
            return;
        }

        int passwordStrength = calculatePasswordStrength(password);
        if (passwordStrength < 1) {
            req.setAttribute("changePasswordMsg", "密码强度不足，请添加更多字符种类，例如大写字母、小写字母或特殊字符");
            req.getRequestDispatcher(MYACCOUNT).forward(req, resp);
            return;
        }

        // Validate repeated password
        if (!Objects.equals(password, password1)) {
            req.setAttribute("changePasswordMsg", "两次输入的密码不一致");
            req.getRequestDispatcher(MYACCOUNT).forward(req, resp);
            return;
        }

        // If validation passed, change the password and username
        if (this.username.equals(this.newusername) || !service.is_repeat(this.newusername)) {
            service.changePassword(this.username, this.password);
            service.changeUsername(this.newusername, this.username);
            session.setAttribute("password", this.password);
            session.setAttribute("username", this.newusername);
            this.account = service.getAccountByUsername(this.newusername);
            session.setAttribute("loginAccount", this.account);
        } else {
            req.setAttribute("changePasswordMsg", "新用户名已存在");
            req.getRequestDispatcher(MYACCOUNT).forward(req, resp);
            return;
        }

        // Logging the change in password
        Account loginAccount = (Account) session.getAttribute("loginAccount");
        if (loginAccount != null) {
            String username = loginAccount.getUsername();
            String strBackUrl = "http://" + req.getServerName() + ":" + req.getServerPort()
                    + req.getContextPath() + req.getServletPath() + "?" + (req.getQueryString());
            LogService logService = new LogService();
            String logInfo = logService.logInfo(new Object[]{" "}) + strBackUrl + "修改了个人密码";
            logService.insertLogInfo(username, logInfo);
        }
        req.setAttribute("changePasswordMsg", "用户名与密码修改成功！");
        req.getRequestDispatcher(MYACCOUNT).forward(req, resp);
    }

    private int calculatePasswordStrength(String password) {
        int level = 0;
        if (password.matches(".*[!@#$].*")) {
            level++;
        }
        if (password.matches(".*[a-z].*")) {
            level++;
        }
        if (password.matches(".*[A-Z].*")) {
            level++;
        }
        return level;
    }
}
